package com.sunshine.lnuplusweb.controller;

import com.sunshine.lnuplusweb.entities.Lesson;
import com.sunshine.lnuplusweb.entities.UserConfig;
import com.sunshine.lnuplusweb.service.LessonService;
import com.sunshine.lnuplusweb.service.ScheduleService;
import com.sunshine.lnuplusweb.service.UserConfigService;
import com.sunshine.lnuplusweb.utils.BackgroundUtils;
import com.sunshine.lnuplusweb.utils.ColorUtils;
import com.sunshine.lnuplusweb.utils.DateUtils;
import com.sunshine.lnuplusweb.utils.Result;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 课程界面控制器
 */
@Controller
public class ScheduleController {

    @Resource
    private UserConfigService userConfigService;

    @Resource
    private LessonService lessonService;

    /**
     * 这里为什么不像其他地方一样使用Map传值给前端？
     * 因为这里为了换行，需要传递<br>过去让th:utext接收，而用Map会转义<>导致前端出错
     * 为了正常使用，改用了Model
     * @param httpSession
     * @param model
     * @return
     */
    @GetMapping(value = {"/schedule","/schedule.html"})
    public String schedule(HttpSession httpSession, Model model) {
        String userId = (String) httpSession.getAttribute("userId");
        if (userId != null) {
            model.addAttribute("login", true);
            model.addAttribute("userId", "欢迎 " + httpSession.getAttribute("userId"));

            int scheduleId = userConfigService.getNowScheduleId(userId);
            model.addAttribute("schedule_id", scheduleId);
        } else {
            model.addAttribute("login", false);
        }
        //背景图片地址
        model.addAttribute("background_url", BackgroundUtils.getBackgroundUrl(new Date()));

        return "schedule";
    }

    //现在显示的与真实的差，默认为0就是显示本周
    private int nowCha = 0;

    @GetMapping(value = {"/lesson", "/lesson_detail"})
    public String lesson(HttpSession httpSession, Model model, HttpServletRequest request){
        String userId = (String) httpSession.getAttribute("userId");
        if (userId != null) {
            int scheduleId = userConfigService.getNowScheduleId(userId);
            if (-1 == scheduleId) {
                //还没有设置课表
                model.addAttribute("lesson_list", null);
            } else {
                //获取课表
                List<Lesson> lessonList = lessonService.getAllLessonByScheduleId(scheduleId);

                //设置课程格子背景颜色
                ColorUtils colorUtils = new ColorUtils();
                for (Lesson lesson : lessonList){
                    //如果没有用户自定义的颜色，那么我们进行默认颜色设置
                    if (lesson.getColor().equals("0")) {
                        lesson.setColor(colorUtils.getColor(lesson.getLessonId()));
                    }
                }

                model.addAttribute("lesson_list", lessonList);


                //设置本周的时间信息，这个本周时显示的本周，而非实际的本周
                long chaTime = nowCha * 7 * 24 * 60 * 60 * 1000L;
                model.addAllAttributes(setDateInfo(DateUtils.getNowLongTime() + chaTime));

                //添加用户配置
                model.addAttribute("user_config", userConfigService.getUserConfig(userId));
            }
        } else {
            model.addAttribute("lesson_list", null);
        }


        //getRequestURI()就是获取请求的地址，我们就需要把这个地址返回即可，不明白sout一下
        String[] url = request.getRequestURI().split("/");
        return url[url.length - 1];
    }

    @GetMapping({"/schedule_setting"})
    public String scheduleSetting(HttpSession httpSession, Model model) {
        String userId = (String) httpSession.getAttribute("userId");
        //如果获取用户名失败，则返回课表页
        if (null == userId) {
            return schedule(httpSession, model);
        } else {
            UserConfig userConfig = userConfigService.getUserConfig(userId);
            model.addAttribute("user_config", userConfig);
            return "schedule_setting";
        }
    }

    /**
     * 接收前端参数并保存
     * @param weekCount
     * @param height
     * @param textSize
     * @param textColor
     * @param round
     * @param showTeacher
     * @param alpha
     * @param dateColor
     * @param httpSession
     * @return
     */
    @PostMapping({"/schedule_setting"})
    @ResponseBody
    public Result toSaveUserConfig(@RequestParam("week-count") int weekCount,
                                   @RequestParam("height") int height,
                                   @RequestParam("text-size") int textSize,
                                   @RequestParam("text-color") String textColor,
                                   @RequestParam("round") int round,
                                   @RequestParam("show-teacher") Boolean showTeacher,
                                   @RequestParam("alpha") float alpha,
                                   @RequestParam("date-color") String dateColor,
                                   HttpSession httpSession) {
        Result result = new Result();
        String userId = (String) httpSession.getAttribute("userId");
        //用户不存在
        if (null == userId) {
            result.setResultCode(Result.RESULT_NOT_FOUND);
        } else {
            try{
                int nowScheduleId = userConfigService.getNowScheduleId(userId);
                UserConfig userConfig = new UserConfig(userId, nowScheduleId, weekCount, height, textSize, textColor, round, showTeacher, alpha, dateColor, false);
                userConfigService.updateUserConfig(userConfig);
                result.setResultCode(Result.RESULT_OK);
            }catch (Exception e) {
                result.setResultCode(Result.RESULT_SERVICE_ERROR);
                result.setMessage(e.toString());
            }
        }
        return result;
    }

    @GetMapping({"/add_lesson"})
    public String addLesson(HttpSession httpSession, Model model) {
        String userId = (String) httpSession.getAttribute("userId");
        //如果获取用户名失败，则返回课表页
        if (null == userId) {
            return schedule(httpSession, model);
        } else {
            return "add_lesson";
        }
    }

    @PostMapping({"/add_lesson"})
    @ResponseBody
    public Result toAddLesson(@RequestParam("lesson-name") String lessonName,
                              @RequestParam("teacher") String teacher,
                              @RequestParam("location") String location,
                              @RequestParam("color") String color,
                              @RequestParam("day-of-week") int dayOfWeek,
                              @RequestParam("start") int start,
                              @RequestParam("end") int end,
                              @RequestParam("weeks") String weeks,
                              HttpSession httpSession) {
        Result result = new Result();
        String userId = (String) httpSession.getAttribute("userId");
        //用户不存在
        if (null == userId) {
            result.setResultCode(Result.RESULT_NOT_FOUND);
        } else {
            try{
                int nowScheduleId = userConfigService.getNowScheduleId(userId);
                Lesson lesson = new Lesson(nowScheduleId, String.valueOf(new Date().getTime()), dayOfWeek, start, 0L, end, 0L, lessonName, teacher, location, weeks, color.replace("#000000", "0"));
                lessonService.insertLesson(lesson);
                result.setResultCode(Result.RESULT_OK);
            }catch (Exception e) {
                result.setResultCode(Result.RESULT_SERVICE_ERROR);
                result.setMessage(e.toString());
            }
        }
        return result;
    }

    @PostMapping({"/delete_lesson"})
    @ResponseBody
    public Result deleteLesson(@RequestParam("lessonId") String lessonId,
                              @RequestParam("start") int start,
                              @RequestParam("end") int end,
                              HttpSession httpSession) {
        Result result = new Result();
        String userId = (String) httpSession.getAttribute("userId");
        //用户不存在
        if (null == userId) {
            result.setResultCode(Result.RESULT_NOT_FOUND);
        } else {
            try{
                int nowScheduleId = userConfigService.getNowScheduleId(userId);
                lessonService.deleteLesson(nowScheduleId, lessonId, start, end);
                result.setResultCode(Result.RESULT_OK);
            }catch (Exception e) {
                result.setResultCode(Result.RESULT_SERVICE_ERROR);
                result.setMessage(e.toString());
            }
        }
        return result;
    }

    @PostMapping({"/switch_week"})
    @ResponseBody
    public Result switchWeek(@RequestParam("now_week") int nowWeek,
                             HttpSession httpSession) {

        Result result = new Result();
        String userId = (String) httpSession.getAttribute("userId");
        //用户不存在
        if (null == userId) {
            result.setResultCode(Result.RESULT_NOT_FOUND);
        } else {
            nowCha = nowWeek - DateUtils.getThisWeek(new Date());
            result.setResultCode(Result.RESULT_OK);
        }
        return result;
    }

    /**
     * 设置前端课表中需要的日期时间信息
     * @param thisWeekLongTime      当前设置的日期是针对哪周设置的，使用long值方便内部调用
     */
    private Map<String, Object> setDateInfo(long thisWeekLongTime){
        Map<String, Object> map = new HashMap<>();
        //设置本周为第几周，请注意，这个“本周”是当前课表显示的是第几周，不是真实的周，真实的周是really_this_week
        map.put("this_week", DateUtils.getThisWeek(thisWeekLongTime));

        /*----------------------------------------------------------*/
        //设置日期栏显示的日期信息，用数组表示，0是月份，1-7是周一到周日
        List<String> dateList = new ArrayList<>();

        /*------------------------*/
        //设置月份
        SimpleDateFormat monthSDF = new SimpleDateFormat("M月");
        dateList.add(0, monthSDF.format(new Date(thisWeekLongTime)));

        /*------------------------*/
        //设置周几，格式：9月30\n周五

        //创建一个日期为thisWeekLongTime的日历对象，用于日期调用
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(thisWeekLongTime);

        //创建周几显示的日期格式化对象
        SimpleDateFormat weekSDF = new SimpleDateFormat("M/d EE");

        //获取今天是一周的周几，用于下方日期相加减
        int todayOfWeek = DateUtils.getDayOfWeek(calendar.get(Calendar.DAY_OF_WEEK));
        for (int i = 1;i<=7;i++) {
            //推算“这天”是哪一天
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + i - todayOfWeek);
            dateList.add(i, weekSDF.format(calendar.getTime()).replace(" ", "<br>"));
            //将日期“推算”回去
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - i + todayOfWeek);
        }
        /*----------------------------------------------------------*/

        //将今天是周几和真实的周推给前端，用于今天块“高亮”显示
        map.put("today_of_week", todayOfWeek);
        map.put("really_this_week", DateUtils.getThisWeek(new Date()));

        map.put("date_list", dateList);

        return map;
    }
}
